﻿using UnityEngine;
using System;

/// <summary>
/// 敌人-炮台1
/// </summary>
public class EnemyTurret1 : Enemy
{
    // 炮口朝向
    internal Vector2 lookAt=LookAtDirection12.Left.ToVector2();
    protected override void Awake()
    {
        base.Awake();
    }


    protected override void Update()
    {
        base.Update();
    }

    protected override void FixedUpdate()
    {
        base.FixedUpdate();
    }

    protected override void InitStateActions()
    {
        state=typeof(EnemyTurret1StateAction_Close);
        stateMachine.Registe(new EnemyTurret1StateAction[] {
            new EnemyTurret1StateAction_Close(this),
            new EnemyTurret1StateAction_Working(this),
            new EnemyTurret1StateAction_Die(this),
        });
    }

    public void Fire()
    {

        Vector2 muzzlePosition = transform.position;
        Vector2 muzzleOffset = Vector2.zero;

        // 计算炮口位置
        if(TryGetComponent(out SpriteRenderer renderer)){
            Vector2 size=renderer.bounds.size;
            float angle=Vector2.SignedAngle(Vector2.right, lookAt);
            float x=Mathf.Cos(Mathf.Deg2Rad*angle)*size.x/2f;
            float y=Mathf.Sin(Mathf.Deg2Rad*angle)*size.y/2f;
            muzzleOffset=new Vector2(x,y);
        }
        muzzlePosition += muzzleOffset;

        // 发射子弹
        GameObject bulletPrefab=Constant.Prefabs.EmenyBullet1.Load();
        GameObject objBullet = Instantiate(bulletPrefab, muzzlePosition, Quaternion.identity);
        if (objBullet.TryGetComponent<Bullet>(out var aBullet))
        {
            BulletMeta bulletMeta=new(){
                sourcePoint=muzzlePosition,
                targetPoint=muzzlePosition+lookAt,
            };
            aBullet.Launch(bulletMeta);
        }
    }

    public override void Die()
    {
        state=typeof(EnemyTurret1StateAction_Die);
    }
}

// 炮台状态类，可以使用炮台类的属性
public abstract class EnemyTurret1StateAction : EnemyStateAction
{
    // 状态上下文中的敌人对象
    protected EnemyTurret1 turret;
    public EnemyTurret1StateAction(EnemyTurret1 turret) : base(turret) {
        this.turret=turret;
    }
}
// 炮台关闭
public class EnemyTurret1StateAction_Close : EnemyTurret1StateAction
{
    public EnemyTurret1StateAction_Close(EnemyTurret1 turret) : base(turret) {}

    public override void FixedUpdate(System.Type inState, out System.Type outState)
    {
        base.FixedUpdate(inState,out outState);
        if(enemy.TryGetComponent(out SpriteRenderer renderer)){
            renderer.sprite=Constant.Sprites["敌-炮台1-关"];
        }
        // 进入镜头则炮台开始工作
        if(enemy.AllInViewPort(0.0f)){
            outState=typeof(EnemyTurret1StateAction_Working);
        }
    }
}

// 炮台运行
public class EnemyTurret1StateAction_Working : EnemyTurret1StateAction
{
    // 炮台朝向和精灵的对应关系
    private struct LookAtSprite{
        public LookAtDirection12 lookAtDirection;
        public Sprite sprite;
    }
    // 炮台旋转间隔48帧
    SeqAction rotateAction = new() { intervalTime = 48f/60f };
    // 射击动作
    SeqAction fireAction = new() { beginWaitTime = 2f, intervalTime = 0.5f };
    // 炮台弹匣
    int boxMagazineSize = 1;


    // 炮台朝向和精灵的对应关系
    static LookAtSprite[] lookAtSpriteConfig;
    static EnemyTurret1StateAction_Working(){
        // 初始化炮台朝向和精灵的对应关系
        lookAtSpriteConfig=new LookAtSprite[]{
            new (){lookAtDirection=LookAtDirection12.Left,sprite=Constant.Sprites["敌-炮台1-左"],},
            new (){lookAtDirection=LookAtDirection12.LeftLeftUp,sprite=Constant.Sprites["敌-炮台1-左上1"],},
            new (){lookAtDirection=LookAtDirection12.UpLeftUp,sprite=Constant.Sprites["敌-炮台1-左上2"],},
            new (){lookAtDirection=LookAtDirection12.Up,sprite=Constant.Sprites["敌-炮台1-上"],},
            new (){lookAtDirection=LookAtDirection12.UpRightUp,sprite=Constant.Sprites["敌-炮台1-右上2"],},
            new (){lookAtDirection=LookAtDirection12.RightRightUp,sprite=Constant.Sprites["敌-炮台1-右上1"],},
            new (){lookAtDirection=LookAtDirection12.Right,sprite=Constant.Sprites["敌-炮台1-右"],},
            new (){lookAtDirection=LookAtDirection12.RightRightDown,sprite=Constant.Sprites["敌-炮台1-右下1"],},
            new (){lookAtDirection=LookAtDirection12.DownRightDown,sprite=Constant.Sprites["敌-炮台1-右下2"],},
            new (){lookAtDirection=LookAtDirection12.Down,sprite=Constant.Sprites["敌-炮台1-下"],},
            new (){lookAtDirection=LookAtDirection12.DownLeftDown,sprite=Constant.Sprites["敌-炮台1-左下2"],},
            new (){lookAtDirection=LookAtDirection12.LeftLeftDown,sprite=Constant.Sprites["敌-炮台1-左下1"],},
        };
    }
    public EnemyTurret1StateAction_Working(EnemyTurret1 turret) : base(turret) {}

    public override void Enter(System.Type lastState, System.Type currentState){
        rotateAction.ReStart();
        fireAction.ReStart();
    }

    public override void FixedUpdate(System.Type inState, out System.Type outState)
    {
        base.FixedUpdate(inState,out outState);

        Vector2 turretPosition=enemy.transform.position;
        Vector2 lookAt=turret.lookAt;
        if(Player.GetNearestPlayerPosition(turretPosition,out Vector2 nearestPlayerPosition)){
            Vector2 targetDirection = nearestPlayerPosition - new Vector2(turretPosition.x, turretPosition.y);
            LookAtDirection12 target = targetDirection.ToLookAtDirection12();
            LookAtDirection12 current = lookAt.ToLookAtDirection12();

            // 旋转炮台
            rotateAction.Update((SeqAction seq) =>
            {
                if (target != current)
                {
                    float angle = Vector2.SignedAngle(current.ToVector2(), target.ToVector2());
                    if (angle > 0)
                    {
                        turret.lookAt = Quaternion.AngleAxis(30, Vector3.forward) * lookAt;
                    }
                    else
                    {
                        turret.lookAt = Quaternion.AngleAxis(-30, Vector3.forward) * lookAt;
                    }
                }
            });

            // 开炮
            if (target == current)
            {
                fireAction.Update((SeqAction seq) =>
                {
                    if (seq.IsFirstAction())
                    {
                        seq.PropertyInteger.Add("boxMagazine", boxMagazineSize);
                    }
                    int boxMagazine = seq.PropertyInteger["boxMagazine"];
                    turret.Fire();
                    if (--boxMagazine <= 0)
                    {
                        fireAction.ReStart();
                    }
                    else
                    {
                        seq.PropertyInteger["boxMagazine"] = boxMagazine;
                    }
                });
            }

            // 根据朝向显示精灵
            if(enemy.TryGetComponent(out SpriteRenderer renderer)){
                renderer.sprite=GetLookAtSprite(lookAt.ToLookAtDirection12());
            }
        }

        // 靠近镜头边界则关闭炮台
        if(!enemy.AllInViewPort(0.0f)){
            outState=typeof(EnemyTurret1StateAction_Close);
        }
    }

    private Sprite GetLookAtSprite(LookAtDirection12 lookAtDirection)
    {
        Sprite ret = null;
        foreach (LookAtSprite config in lookAtSpriteConfig)
        {
            if (config.lookAtDirection == lookAtDirection)
            {
                ret = config.sprite;
                break;
            }
        }
        return ret;
    }

}

// 炮台死亡
public class EnemyTurret1StateAction_Die : EnemyTurret1StateAction
{
    public EnemyTurret1StateAction_Die(EnemyTurret1 turret) : base(turret) {}

    public override void FixedUpdate(System.Type inState, out System.Type outState)
    {
        base.FixedUpdate(inState,out outState);
        GameObject.Instantiate(Constant.Prefabs.EmenyBoom1.Load(),turret.transform.position,Quaternion.identity);
        GameObject.Destroy(turret.gameObject);
    }
}